Intermediate Python

Using functions

You're likely already comfortable with calling functions in Python. One of the first things you were probably taught was how to print() something. As you've continued your learning, you've probably come across a larger number of other ways of calling functions which are similar, but work slightly differently.

In this section we're going to explore how Python works in these situations and how you can understand what's going on.

In terms of calling functions, you have seen:

  • free functions like print() and range()
  • functions on objects (also called "methods") like my_list.append() and my_str.split()

but you will also have written things like the following in your code:

  • data literals like 10, "hello" and [1, 2]
  • syntax like for house in town: and if height > 10:

So far you have probably learned these topics by following tutorials or attending workshops like this one. However, there is a central, official place where all the details of how these things work is written down so let's have an explore.

Go to https://docs.python.org

There are a lot of different sections linked from that page, but the two most important links for us are:

  1. The "Language Reference" (https://docs.python.org/3/reference/) which details all the in-built features of the language. It's quite technical and not the place you'd normally go to learn as a beginner. This covers our "literals" and "syntax" from above.
  2. The "Library Reference" (https://docs.python.org/3/library/) which covers all of the extra functions, classes and modules that Python provides. This is where we find all the cool stuff.

Built-in functions

Python comes with a bunch of functionality that you can use without having to explicitly enable anything. This includes things like integers, strings, lists, print()ing, file open()ing etc.

First, lets have a peek at the "built-in functions". There is a page describing these under the "Library Reference" in a page called Built-in Functions.

Here we find the documentation for many of the functions we've already been using, for example print() and max().

It is worth, over time, becoming familiar with the various functions that are available here. Some are quite useful for everyday work and some are more niche.

Exercise 1

Copy the following code into a new file called hello.py:

my_name = ...

name_length = ...

print(f"Hello {my_name}! Your name is {name_length} characters long")

Replace the first ... with a call to a built-in function which will read input from the person running the script. Replace the second ... with a call to a function which will give the length of the string returned by the first. Search through the built-in functions page to find the appropriate functions.

The script should, when run with python hello.py, then print out:

Please tell me your name:

and wait for you to type your name like:

Please tell me your name: Matt

After pressing enter, it should then print out:

Please tell me your name: Matt
Hello Matt! Your name is 4 characters long

answer

Built-in types

As well as the free-standing built-in functions, Python has a bunch of built-in data types. This includes the data types you've already been using like integers, strings and lists. The details of them all are under the "Library Reference" on a page called Built-in Types.

These types being built-in means that you don't need to explicitly enable their use and most have core-language syntax to create them.

For example, the code

animal = "horse"

creates a variable called animal from the string literal "horse" which is of the type str. This data type is built into the language and so the functionality that it has is documented on the built-in types page under str.

This means that when we do:

animal.capitalize()

it is looking at the data type of the variable animal, seeing that it is a str and then using the capitalize function that's available for that type to do the work.

The documentation for all the built-in types is all on that page so it's the place to go to check what you can do with a str, an int, a list or a dict. There's also a few other built-in types you might want to look into in the future such as complex, set and tuple.

Exercise 2

Have a look at the documentation page for the functions that you can call on strings.

Experiment with one or two and see if you can understand the documentation. Start by trying to answer the following:

  1. Given a string like s = "what is your name", find a function which can split s into a list like ["what", "is", "your", "name"]
  2. Given a list like ["a", "b", "c"], find a function which can join it together into a string like "a-b-c"

answer

Importing functions from modules

While there are a good number of built-in functions and types, and you can go a long way without needing anything more, they are ultimately limited. Luckily, Python has a "batteries included" philosophy and provides a lot of additional functionality in its "standard library".

The functionality provided by the standard library is provided in a series of modules, each of whch serves a particular purpose. The things in the standard library are always installed in any version of Python you have and you can rely on them being there.

Note that even though they are always accessible, they do not count as "built-in" as in Python terms, that means something which you can use without having to access any extra modules.

The math module

Let's start by looking at one of the modules. On the Standard Library page, if you scroll past the "built-in" sections you'll find a set of groups of modules. There are about 200 modules in total, some very useful and some very niche.

If you carry on down the page you'll see, "math — Mathematical functions" which is where we are going to look first.

This module provides a bunch of mathematical tools such as averages, trigonometry etc.

You can get access to the module by importing it by name:

import math

Once it is imported, you can use any of the functions inside it by typing the name of the module, followed by a dot, followed by the name of the function. So to call the square root function you would do:

imports.py
import math

print(math.sqrt(25))
$
python imports.py
5.0

You can think of this as saying "from the math module that I've just imported, get the sqrt function inside it and call it".

If you want to grab a specific function out of a module so that you can call it without specifying the module name, you can do:

imports.py
from math import sqrt

print(sqrt(25))
$
python imports.py
5.0

We've seen two examples of places where dot . is used when calling functions in Python:

  1. calling a method on a variable like with my_list.append() or my_string.split(),
  2. calling a function from an imported module like math.sqrt().

In both these cases the dot is doing a very similar job. It's saying "look inside the thing on the left of the dot for a thing called ...". In some cases, it's looking inside a data type, and in other it's looking inside a module.

Exercise 3

Change the message in encode.py to use both upper and lower case letters:

message = "SOS We have hit an iceberg and need help quickly"

When you now run the script with python encode.py you will find that it gives you a KeyError. This is because it is looking for an upper case "S" in the dictionary letter_to_morse and not finding one (dictionary keys are case-sensitive).

Read through the documentation for the string methods to find one that might help convert the letter you have into one that matches the keys in the dictionary. You should be able to add a single line of code in the loop straight after for letter in message:.

answer